public class demo1 {
    public static void main(String[] args) {
        Box box = new Box();
        Producer p = new Producer(box, "p");
        Consumer c = new Consumer(box, "c");
        p.start();
        c.start();
    }
}
class Box {
    private int value;
    private boolean available = false;
    public synchronized int get() {
        while (available == false) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        available = false;
        // 通知生产者数据已经被取走，可以再次写入数据
        notifyAll();
        return value;
    }
    public synchronized void put(int value) {
        while (available == true) {
            try {
                // 等待消费者取走数据
                wait();
            } catch (InterruptedException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        this.value = value;
        available = true;
        // 通知消费者可以来取数据
        notifyAll();
    }
}
class Consumer extends Thread {
    private Box box;
    private String name;
    public Consumer(Box b, String n) {
        box = b;
        name = n;
    }
    public void run() {
        int value = 0;
        for (int i = 1; i < 6; i++) {
            value = box.get();
            System.out.println("Consumer " + name + " consumed: " + value);
            try {
                sleep(  1000);
            } catch (InterruptedException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }
}
class Producer extends Thread {
    private Box box;
    private String name;
    public Producer(Box b, String n) {
        box = b;
        name = n;
    }
    public void run() {
        for (int i = 1; i <6;i++) {
            box.put(i);
            System.out.println("Producer " + name + " produced: " + i);
            try {

                sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }
}
